/* The file is saved in UTF-8 codepage.
 * Check: «Stereotype», Section mark-§, Copyright-©, Alpha-α, Beta-β, Smile-☺
 */
package cz.pecinovsky.english.lootp._134_;


import cz.pecinovsky.english.lootp._000_.Run;

import cz.pecinovsky.english.lootp.manager.IMoveable;
import cz.pecinovsky.english.lootp.manager.Multimover;
import cz.pecinovsky.english.lootp.manager.Mover;


import cz.pecinovsky.english.lootp.manager.CanvasManager_Envelope.               CanvasManager;


import cz.pecinovsky.english.lootp._134_.IModular_134_.                          IModular;
import cz.pecinovsky.english.lootp._134_.IRotable_136_.                          IRotable;
import cz.pecinovsky.english.lootp._134_.Rotable_136_.                           Rotable;
import cz.pecinovsky.english.lootp._134_.Ring_134_.                             Ring;


//import cz.pecinovsky.english.lootp._134_.TestUtility_134_.TestUtility;
////////////////////////////////////////////////////////////////////////////////
//%%+  +++++ End of ignored starting test - place for imports +++++
//%I+ =133c
//
//import správce.IO;
//import správce.IMoveable;
//import správce.Position;
//import správce.Mover;
//import správce.CanvasManager;
//
////import správce.*;
//%I-
//%I+ >=133x
//
//import cz.pecinovsky.english.lootp.canvasmanager.IMoveable;
//import cz.pecinovsky.english.lootp.canvasmanager.Mover;
//import cz.pecinovsky.english.lootp.canvasmanager.CanvasManager;
//%I-
//%I+ >136
//import cz.pecinovsky.english.lootp.canvasmanager.Multimover;
//%I-
//%A+ >=133x

import cz.pecinovsky.english.lootp.utility.IO;
import cz.pecinovsky.english.lootp.utility.Position;
//%A-
//%A+ >142

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
//%A-
//%X+ xxxxx Start of the ovejumped text with declaration of the envelope xxxxx
/*******************************************************************************
 *<pre>
 * Předchozí:   Není - toto_je_nově_definovaná_třída
 *              Ttt v projektu Ppp
 * Následující: Prozatím není
 *
 * Projekt  Ppp
 *   + Přidáno
 *   - Odebráno
 *   ~ Změněno
 *</pre>
 */
public class TestUtility_134_
{    private TestUtility_134_() {}   static
////////////////////////////////////////////////////////////////////////////////
//%X- ----- End of the ovejumped text with declaration of the envelope -----


/*******************************************************************************
 * Knihovní třída {@code TestUtility} obsahuje sbírku pomocných metod
 * používaných testovacími třídami objektů implementujících rozhraní
 * {@link IModular}.
 *
 * @author Rudolf PECINOVSKÝ
 * @version 6.03.2017 — 2010-11-08
 */
public class TestUtility extends junit.framework.TestCase
{
//== CONSTANT CLASS ATTRIBUTES =================================================

    private static final CanvasManager CM = CanvasManager.getInstance();



//== VARIABLE CLASS ATTRIBUTES =================================================

    /** Position, na níž se bude přesouvat objekt testovaný v metodě
     *  {@link #positionSize(IModular)}. */
    private static Position position;

    /** Velikost menšího z modulů, které se budou nastavovat objektu
     *  testovanému v metodě {@link #positionSize(IModular)}. */
    private static int smallModule;

    /** Velikost většího z modulů, které se budou nastavovat objektu
     *  testovanému v metodě {@link #positionSize(IModular)}. */
    private static int bigModule;



//== STATIC CONSTRUCTOR (CLASS INITIALIZER, STATIC INICITALIZING BLOCK) ========
//== CONSTANT INSTANCE ATTRIBUTES ==============================================
//== VARIABLE INSTANCE ATTRIBUTES ==============================================
//== CLASS GETTERS AND SETTERS =================================================

    /***************************************************************************
     * Vyzkouší změny pozice a velikosti zadaného objektu;
     * parametry testu je třeba předem nastavit pomocí metody
     *
     * @param position    Position, na kterou se testovaný objekt přesune
     * @param small      Malá velikost modulu, jež se testovanému objektu zadá
     * @param big     Velká velikost modulu, jež se testovanému objektu zadá
     */
    public static void setPositionModules(Position position, int small, int big)
    {
        TestUtility.position    = position;
        TestUtility.smallModule = small;
        TestUtility.bigModule   = big;
    }



//== OTHER NON-PRIVATE CLASS METHODS ===========================================
//%A+ >136

    /***************************************************************************
     * Vyčistí plátno, postaví small okruh a objede jej zadaným otočným objektem.
     * Zakomentovaný příkaz umožňuje postavit a objíždět okruh kolem plátna.
     *
     * @param objekt Testovaný otočný objekt
     */
    public static void runRing(IRotable objekt)
    {
        CM.removeAll();
        int k = CM.getStep();
//        Ring  ring  = Ring.elko(new Position(k,k));
        Ring  ring  = Ring.čtverec(new Position(k,k));
        Rotable rotable = new Rotable(objekt);
        rotable.goRound(ring);


        IO.inform("Až se pokocháš, stiskni OK");
        Multimover.getInstance().zastavVše();
    }

//%A-

    /***************************************************************************
     * Vyzkouší změny pozice a velikosti zadaného objektu;
     * parametry testu je třeba předem nastavit pomocí metody
     *
     * @param objekt Testovaný objekt
     */
    public static void positionSize(IModular objekt)
    {
        positionSize(objekt, position, smallModule, bigModule);
    }


    /***************************************************************************
     * Vyzkouší změny pozice a velikosti zadaného objektu s použitím
     * zadaných parametrů.
     *
     * @param objekt    Testovaný objekt
     * @param pozice    Position, na kterou se testovaný objekt přesune
     * @param small      Malá velikost modulu, jež se testovanému objektu zadá
     * @param big     Velká velikost modulu, jež se testovanému objektu zadá
     */
    public static void positionSize(IModular objekt,
                                    Position pozice, int small, int big)
    {
        final int ms = 500;
        objekt.setPosition(pozice.x, pozice.y);
        IO.pause(ms);
        objekt.setModule(big);
        IO.pause(ms);
        objekt.setModule(small);
        IO.pause(ms);
        CM.remove(objekt);
        IO.pause(ms);
    }


    /***************************************************************************
     * Prohodí pozice zadaných objektů a nechá zkontrolovat,
     * zda si objekty své pozice doopravdy vyměnily.
     *
     * @param o1 První objekt
     * @param o2 Druhý objekt
     */
    public static void swapPositionsWithCheck(IMoveable o1, IMoveable o2)
    {
        Mover mover = new Mover(10);
        Position p1 = o1.getPosition();
        Position p2 = o2.getPosition();

        System.out.println("Výchozí: " + p1 + " <--> " + p2);

        mover.moveTo(p2, o1);
        mover.moveTo(p1, o2);

        System.out.println("Cílová:  " + o1.getPosition() +
                              " <--> " + o2.getPosition() + "\n");

        assertEquals(p1, o2.getPosition());
        assertEquals(p2, o1.getPosition());
    }

//%A+ >142

    /***************************************************************************
     * Seřadí objekty v seznamu podle velikosti modulu,
     * stejně velké objekty pak seřadí nejprve podle vodorovné souřadnice
     * a když mají i tu stejnou, tak podle svislé souřadnice;
     * výsledný seznam vytiskne na standardní výstup.
     *
     * @param seznam Seznam s řazenými objekty
     */
    public static void seřaďSeznam(List<IModular> seznam)
    {
        Collections.sort(seznam, new CompModulXY());
        System.out.println("\nModulově a pozičně seřazené instance:");
        int i = 0;
        for (IModular im : seznam) {
            System.out.println(++i + ".  " + im);
        }
    }

//%A-
//%A+ >143

    /***************************************************************************
     * Vytvoří nový seznam jako instanci třídy {@link ArrayList}
     * a naplní jej hodnotami zadanými jako parametry.
     *
     * @param pole  Hodnoty, jimiž bude vytvořený seznam inicializován
     * @return Nový seznam naplněný zadanými hodnotami
     */
    public static List<IModular> newListIModulový(IModular... pole)
    {
        List<IModular> seznam = new ArrayList<IModular>();
        for (IModular im : pole) {
            seznam.add(im);
        }
        return seznam;
    }

//%A-


//##############################################################################
//== CONSTUCTORS AND FACTORY METHODS ===========================================

    /** Soukromý konstruktor brání vytvoření instancí. */
    private TestUtility(String name) {}

//== PREPARATION AND CLEANING THE FIXTURE ======================================
//== PRIVATE AND AUXILIARY CLASS METHODS =======================================
//== PRIVATE AND AUXILIARY INSTANCE METHODS ====================================
//== EMBEDDED TYPES AND INNER CLASSES ==========================================
//%A+ >142

    private static class CompModulXY implements Comparator<IModular>
    {
        /***********************************************************************
         * Porovná objekty podle velikosti jejich modulu, stejně velké objekty
         * pak nejprve podle vodorovné souřadnice (menší souřadnice dopředu)
         * a když mají i tu stejnou, tak podle svislé souřadnice
         * (opět menší souřadnice dopředu).
         *
         * @param o1  První z porovnávaných objektů
         * @param o2  Druhý z porovnávaných objektů
         * @return Výsledek porovnání
         */
        @Override
        public int compare(IModular o1, IModular o2)
        {
            //Má-li být o1 < o2, musí se vrátit záporné číslo
            //Větší má být před menším =>  (o1 < o2) <=> ((o2-o1) < 0)
            if (o1.getModule() != o2.getModule()) {
                return o2.getModule() - o1.getModule();
            } else {
                //U souřadnic se dopředu probojuje naopak ten menší, takže
                //Menší má být před větším =>  (o1 < o2) <=> ((o1-o2) < 0)
                Position p1 = o1.getPosition();
                Position p2 = o2.getPosition();
                if (p2.x != p1.x) {
                    return p1.x - p2.x;
                } else {
                    return p1.y - p2.y;
                }
            }
        }
    }



//%A-
//== THE TESTS =================================================================
//
//     /***************************************************************************
//      *
//      */
//     public void testXXX()
//     {
//     }
    }

//%%- ---- Start of the ovejumped text with closing of the envelope ----
////////////////////////////////////////////////////////////////////////////////
//== TESTING CLASSES AND METHODS ===============================================
//Není-li třída testovací, následující dvě metody se smažou
//%X+   Metoda připravená k vložení do testovacích tříd
     /** */
     public void testFixture() {}
//%X-


    /***************************************************************************
     * Třída, jejíž instance má na starosti úklid mezi jednotlivými testy,
     * který není možno zakomponovat do metody {@code tearDown()},
     * dokud nebudou studenti umět programovat.
     */
    private static class TearDown implements Run.ITD
    {
        /** {@inheritDoc} */
        @Override
        public void cleanUp()
        {
//            Canvas.clearCanvas();
//            CanvasManager.getInstance().removeAll();
        }
    }


    /***************************************************************************
     * Test method.
     */
    public static void test()
    {
////Nejedná-li se o testovací třídu, celý blok lze smazat
//        junit.textui.TestRunner.run(suite());
//        junit.textui.TestRunner.run(new Třída("test"));
//        Run.tests(Test.class,
//                new TearDown(),
//                "testFixture",
//                "");
        System.exit(0);
    }
    /** @param args Parametry příkazového řádku - nepoužívané. */
    public static void main(String[] args)  {  test();  }
}
